package btstack
/*
#include "btstack.h"
*/
import "C"
import (
	"bytes"
	"encoding/binary"
	"net"
)

type EventPoweronFailedPacket struct {
	packet []byte
}


type EventStatePacket struct {
	packet []byte
}

func (p *EventStatePacket) State() HciState {
	return HciState(p.packet[2])
}


type EventAdvertisingReportPacket struct {
	packet []byte
	addr net.HardwareAddr
	flags uint8
	name string
}

func parseAdvertisingReportPacket(p *EventAdvertisingReportPacket) *EventAdvertisingReportPacket {
	addr := p.packet[4:10]
	for i, j := 0, len(addr)-1; i < j; i, j = i+1, j-1 {
		addr[i], addr[j] = addr[j], addr[i]
	}
	p.addr = addr

	advLen := p.packet[11]
	advData := p.packet[12 : 12+advLen]

	for len(advData) > 0 {
		dataType := advData[1]
		size := advData[0] - 1
		data := advData[2 : 2+size]

		switch dataType {
		case C.BLUETOOTH_DATA_TYPE_FLAGS:
			p.flags = data[0]
		case C.BLUETOOTH_DATA_TYPE_SHORTENED_LOCAL_NAME:
			fallthrough
		case C.BLUETOOTH_DATA_TYPE_COMPLETE_LOCAL_NAME:
			p.name = string(data)
		}

		advData = advData[2+size:]
	}

	return p
}

func (p *EventAdvertisingReportPacket) Type() AdvType {
	return AdvType(p.packet[2])
}

func (p *EventAdvertisingReportPacket) AddressType() BdAddrType {
	return BdAddrType(p.packet[3])
}

func (p *EventAdvertisingReportPacket) Address() net.HardwareAddr {
	return p.addr
}

func (p *EventAdvertisingReportPacket) Rssi() int8 {
	return int8(p.packet[10])
}

func (p *EventAdvertisingReportPacket) Name() string {
	return p.name
}

func (p *EventAdvertisingReportPacket) Flags() AdFlags {
	return AdFlags(p.flags)
}

type EventLeConnectionCompletePacket struct {
	packet []byte
}

func (p *EventLeConnectionCompletePacket) Handle()  uint16 {
	bytesBuffer := bytes.NewBuffer(p.packet[4:6])
	var x uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &x)
	return x
}

func (p *EventLeConnectionCompletePacket) Interval()  float32 {
	bytesBuffer := bytes.NewBuffer(p.packet[14:16])
	var interval uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &interval)

	fraction := 25 * (interval & 3) / 10

	if fraction < 10 {
		return float32(interval * 125 / 100) + float32(fraction) / 10
	} else {
		return float32(interval * 125 / 100) + float32(fraction) / 100
	}
}

func (p *EventLeConnectionCompletePacket) Latency()  uint16 {
	bytesBuffer := bytes.NewBuffer(p.packet[16:18])
	var x uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &x)
	return x
}

func (p *EventLeConnectionCompletePacket) Status()  uint8 {
	return p.packet[3]
}

func (p *EventLeConnectionCompletePacket) Role()  HciRole {
	return HciRole(p.packet[6])
}


type EventDisconnectionCompletePacket struct {
	packet []byte
}

func (p *EventDisconnectionCompletePacket) Handle() uint16 {
	bytesBuffer := bytes.NewBuffer(p.packet[3:5])
	var x uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &x)
	return x
}

func (p *EventDisconnectionCompletePacket) Status() uint8 {
	return p.packet[2]
}

func (p *EventDisconnectionCompletePacket) Reason() uint8 {
	return p.packet[5]
}


type EventLeServiceQueryResultPacket struct {
	packet []byte
}

func (p *EventLeServiceQueryResultPacket) Service() *GattClientServiceType {
	var s GattClientServiceType

	packet := C.CBytes(p.packet)
	defer C.free(packet)

	C.gatt_event_service_query_result_get_service((*C.uint8_t)(packet), &s.s)

	return &s
}


type EventCharacteristicQueryResult struct {
	packet []byte
}

func (p *EventCharacteristicQueryResult) Characteristic() *GattClientCharacteristicType {
	var c GattClientCharacteristicType

	packet := C.CBytes(p.packet)
	defer C.free(packet)

	C.gatt_event_characteristic_query_result_get_characteristic((*C.uint8_t)(packet), &c.c)

	return &c
}

type EventQueryCompletePacket struct {
	packet []byte
}

func (p *EventQueryCompletePacket) Handle() uint16 {
	bytesBuffer := bytes.NewBuffer(p.packet[2:4])
	var x uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &x)
	return x
}

func (p *EventQueryCompletePacket) AttStatus() uint8 {
	return p.packet[4]
}


type EventRssiMeasurementPacket struct {
	packet []byte
}

func (p *EventRssiMeasurementPacket) Handle() uint16 {
	bytesBuffer := bytes.NewBuffer(p.packet[2:4])
	var x uint16
	binary.Read(bytesBuffer, binary.LittleEndian, &x)
	return x
}

func (p *EventRssiMeasurementPacket) Rssi() int8 {
	return int8(p.packet[4])
}